package com.kingmed.kmss.admin.modules.sys.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kingmed.kmss.admin.modules.sys.mapper.SysSequenceMapper;
import com.kingmed.kmss.admin.modules.sys.model.SysSequence;
import com.kingmed.kmss.admin.modules.sys.service.SysSequenceService;
import com.kingmed.kmss.common.constant.common.CommonConstants;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.text.NumberFormat;

/**
 * <p>
 * 流水号 服务实现类
 * </p>
 *
 * @author liangzhi
 * @since 2023-06-08
 */
@Service
public class SysSequenceServiceImpl extends ServiceImpl<SysSequenceMapper, SysSequence> implements SysSequenceService {


    @Override
    public String genNextVal(String bizKey, Integer len, Integer step) {
        SysSequence sequence = super.getOne(new QueryWrapper<SysSequence>().lambda().eq(SysSequence::getBizKey, bizKey).last(CommonConstants.LIMIT_ONE));
        if (ObjectUtil.isNull(sequence)) {
            sequence = new SysSequence();
            sequence.setSeqNum(1L);
            sequence.setBizKey(bizKey);
            try {
                super.save(sequence);
                return this.formatLen(sequence.getSeqNum(), len);
            } catch (DuplicateKeyException e) {
                log.error("键冲突，重新生成", e);
                return this.genNextVal(bizKey, len, step);
            }

        }
        int i = super.getBaseMapper().incrementSeq(sequence, step);
        if (i > 0) {
            return this.formatLen(sequence.getSeqNum() + step, len);
        }
        return this.genNextVal(bizKey, len, step);
    }


    private String formatLen(Long seqNum, Integer len) {
        if (ObjectUtil.isNull(len)) {
            return String.valueOf(seqNum);
        }
        NumberFormat numberFormat = NumberFormat.getNumberInstance();
        numberFormat.setMinimumIntegerDigits(len);
        numberFormat.setGroupingUsed(false);
        return numberFormat.format(seqNum);
    }
}
